﻿using Domain.IRepositorys;
using Domain.Services;
using DTO;
using Infrastructure.Job;
using Infrastructure.UniOfWorkBase;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Application.Job
{
    [Job("once")]
    public class IMMessageHandlerJob : AbstractJob
    {
        //public TaskService taskService { get; set; }
        public IEFUnitOfWork efUnitOfWork { get; set; }
        public MsgPulishService msgPulishService { get; set; }
        public ILogger<TakeTaskOutTimeJob> Logger { get; set; }
        public IUserRepository userRepository { get; set; }
        public IConfiguration configuration { get; set; }

        public override void Run()
        {
            var connectionStr = configuration.GetValue<string>("RabbitMQ.ConnectionStr");
            var connectionArr = connectionStr.Split(",");

            var strArr = connectionArr[0].Split(";");

            var hostStr = strArr[0].Split("=")[1];
            var virtualHostStr = strArr[1].Split("=")[1];
            var usernameStr = strArr[2].Split("=")[1];
            var passwordStr = strArr[3].Split("=")[1];

            var factory = new ConnectionFactory() { HostName = hostStr,VirtualHost=virtualHostStr, UserName = usernameStr, Password = passwordStr };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {

                channel.QueueDeclare(queue: "openfiremsg",
                                     durable: true,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);
                channel.QueueDeclare(queue: "openfiremsg_miss",
                                     durable: true,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);
                //channel.ExchangeDeclare("openfiremsg_miss", ExchangeType.Direct, true, false);
                //channel.QueueBind("openfiremsg_miss", "", "openfiremsg_miss");

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body.ToArray();
                    var message = Encoding.UTF8.GetString(body);

                    try
                    {
                        var dto = JsonConvert.DeserializeObject<OpenFireMsgDto>(message);

                        var map = new Dictionary<string, object>();
                        map.Add("from",$"{dto.msgfrom.node}@{dto.msgfrom.domain}");
                        map.Add("frompic", dto.msgfrompic);
                        map.Add("to", $"{dto.msgto.node}@{dto.msgto.domain}");
                        map.Add("uid", dto.uid);
                        map.Add("name", dto.name);

                        var u = userRepository.Entities.FirstOrDefault(i=>i.Phone==dto.uid);

                        if (u == null)
                        {
                            var properties = channel.CreateBasicProperties();
                            //队列持久化
                            properties.Persistent = true;
                            properties.Headers.Add("x-errormsg", "User Not Find");
                            channel.BasicPublish("", "openfiremsg_miss", properties, body);

                            return;
                        }


                        msgPulishService.SendMsg(u.ID,dto.name,dto.msgbody, map);
                    }
                    catch (Exception ex)
                    {
                        var properties = channel.CreateBasicProperties();
                        //队列持久化
                        properties.Persistent = true;
                        properties.Headers.Add("x-errormsg", ex.Message);
                        properties.Headers.Add("x-errorst", ex.StackTrace);
                        channel.BasicPublish("", "openfiremsg_miss", properties, body);

                        return;
                    }
                };
                channel.BasicConsume(queue: "openfiremsg",
                                     autoAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}
